; Problem 1 : Write a program in 8051 assembly which will display "WEL LAB EE 309" on the first
; line and your name on the second line. Display the two lines so that they are left aligned.
;
; Next, change the program to display the same text centred on each line. This is to be
; done by setting the data address memory to the correct value before sending text to the
; display.
;
; Finally, write a version in which characters are inserted from the left one by one with a
; delay of 1 second and when the display is complete, the cursor starts blinking.

;Displaying left to right "WEL LAB EE 309"

ORG 0000H
LJMP START

ORG 0100H
START: NOP
RS EQU P0.0
RW EQU P0.2
EN EQU P0.3
lcd EQU P2

;Initialise some memory with "WEL LAB EE 309"
MOV 80H,#57H
MOV 81H,#45H
MOV 82H,#4CH
MOV 83H,#20H
MOV 84H,#4CH
MOV 85H,#41H
MOV 86H,#42H
MOV 87H,#20H
MOV 88H,#45H
MOV 89H,#46H
MOV 8AH,#20H
MOV 8BH,#33H
MOV 8CH,#30H
MOV 8DH,#39H

;busy wait
LCALL is_busy
LCALL write_cmd
MOV B,#0EH
MOV R0,#80H
loop_write: MOV A,@R0 
	LCALL write_data
	INC @R0
	DJNZ B, loop_write


write_cmd: NOP
	LCALL is_busy
	MOV lcd,#38H 	; configure the LCD, we need to send a function set command first.
					; this sets the LCD to display over 2 lines, 8 bit data interface
					; equiv to 00111000 , 000(DL)(N)(F)00
	LCALL is_busy
	MOV lcd,#0EH	; turns on the display
	LCALL is_busy
	MOV lcd,#06H	; will set the cursor to increment
	LCALL is_busy
	MOV lcd,#01H 	; clear the screen, optional
	RET

;This line is driven low at the start of data transfer. The RS, RW and data lines are now driven to their desired values. EN
;is then taken high. This tells the 44780 to look for a command/data transfer. Finally, EN is
;taken down again. 44780 acts on the command/data only when EN has a downward transition
write_data: NOP
	LCALL is_busy
	CLR EN 	; make EN 0
			; wait for long enough time...
	;set RS RW lcd
	SETB RS
	CLR RW
	;to set
	MOV lcd,A
	SETB EN
		;WAIT
		;WAIT
	RET

is_busy: NOP
	MOV A,lcd ; check if the RS is 
	ANL A,#80H ;make all other bits 0 other than MSB
	JNZ is_busy ;if not zero, wait
	RET ; if zero then return, it's ready to write
END